package com.winning.pmph.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.winning.pmph.entity.*;
import com.winning.pmph.mapper.DataPermissionMapper;
import com.winning.pmph.utils.PMPHAppUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Transactional
public class DataPermissionService extends ServiceImpl<DataPermissionMapper, DataPermission> {

    @Resource
    private DataPermissionService bookPermissionService;

    public List<String> getCrtUserKnowledgeLibPermission() {
        User crtUser = PMPHAppUtil.getCrtUser();
        // 查看当前用户的数据权限;
        List<DataPermission> crtUserDataPermissionList = lambdaQuery().eq(DataPermission::getUserName, crtUser.getUserName()).list();
        if (CollectionUtils.isNotEmpty(crtUserDataPermissionList)) {
            // 当前用户数据权限, 最多只有一条, 如果不为空(说明有限制), 直接返回, 否则取角色权限;
            DataPermission dataPermission = crtUserDataPermissionList.get(0);
            if (CollectionUtils.isNotEmpty(dataPermission.getKnowledgeLibIdArray())) {
                return dataPermission.getKnowledgeLibIdArray().toJavaList(String.class);
            }
        }
        // 当前用户数据权限不存在(或无限制), 则查询当前用户所有角色的数据权限, 取交集返回;
        return lambdaQuery().in(DataPermission::getRoleId, crtUser.getRoleIds()).list()
                .stream().filter(item -> CollectionUtils.isNotEmpty(item.getKnowledgeLibIdArray()))
                .flatMap(item -> item.getKnowledgeLibIdArray().toJavaList(String.class).stream())
                .distinct().collect(Collectors.toList());
    }

    public List<String> getCrtUserEditKnowledgeLibPermission() {
        User crtUser = PMPHAppUtil.getCrtUser();
        // 查看当前用户的数据权限;
        List<DataPermission> crtUserDataPermissionList = lambdaQuery().eq(DataPermission::getUserName, crtUser.getUserName()).list();
        if (CollectionUtils.isNotEmpty(crtUserDataPermissionList)) {
            // 当前用户数据权限, 最多只有一条, 如果不为空(说明有限制), 直接返回, 否则取角色权限;
            DataPermission dataPermission = crtUserDataPermissionList.get(0);
            if (CollectionUtils.isNotEmpty(dataPermission.getEditKnowledgeLibIdArray())) {
                return dataPermission.getEditKnowledgeLibIdArray().toJavaList(String.class);
            }
        }
        // 当前用户数据权限不存在(或无限制), 则查询当前用户所有角色的数据权限, 取交集返回;
        return lambdaQuery().in(DataPermission::getRoleId, crtUser.getRoleIds()).list()
                .stream().filter(item -> CollectionUtils.isNotEmpty(item.getEditKnowledgeLibIdArray()))
                .flatMap(item -> item.getEditKnowledgeLibIdArray().toJavaList(String.class).stream())
                .distinct().collect(Collectors.toList());
    }

    public List<String> getCrtUserPushKnowledgeLibPermission() {
        User crtUser = PMPHAppUtil.getCrtUser();
        // 查看当前用户的数据权限;
        List<DataPermission> crtUserDataPermissionList = lambdaQuery().eq(DataPermission::getUserName, crtUser.getUserName()).list();
        if (CollectionUtils.isNotEmpty(crtUserDataPermissionList)) {
            // 当前用户数据权限, 最多只有一条, 如果不为空(说明有限制), 直接返回, 否则取角色权限;
            DataPermission dataPermission = crtUserDataPermissionList.get(0);
            if (CollectionUtils.isNotEmpty(dataPermission.getPushKnowledgeLibIdArray())) {
                return dataPermission.getPushKnowledgeLibIdArray().toJavaList(String.class);
            }
        }
        // 当前用户数据权限不存在(或无限制), 则查询当前用户所有角色的数据权限, 取交集返回;
        return lambdaQuery().in(DataPermission::getRoleId, crtUser.getRoleIds()).list()
                .stream().filter(item -> CollectionUtils.isNotEmpty(item.getPushKnowledgeLibIdArray()))
                .flatMap(item -> item.getPushKnowledgeLibIdArray().toJavaList(String.class).stream())
                .distinct().collect(Collectors.toList());
    }

    public List<String> getCrtUserJournalPermission() {
        User crtUser = PMPHAppUtil.getCrtUser();
        // 查看当前用户的数据权限;
        List<DataPermission> crtUserDataPermissionList = lambdaQuery().eq(DataPermission::getUserName, crtUser.getUserName()).list();
        if (CollectionUtils.isNotEmpty(crtUserDataPermissionList)) {
            // 当前用户数据权限, 最多只有一条, 如果不为空(说明有限制), 直接返回, 否则取角色权限;
            DataPermission dataPermission = crtUserDataPermissionList.get(0);
            if (CollectionUtils.isNotEmpty(dataPermission.getJournalIdArray())) {
                return dataPermission.getJournalIdArray().toJavaList(String.class);
            }
        }
        // 当前用户数据权限不存在(或无限制), 则查询当前用户所有角色的数据权限, 取交集返回;
        return lambdaQuery().in(DataPermission::getRoleId, crtUser.getRoleIds()).list()
                .stream().filter(item -> CollectionUtils.isNotEmpty(item.getJournalIdArray()))
                .flatMap(item -> item.getJournalIdArray().toJavaList(String.class).stream())
                .distinct().collect(Collectors.toList());
    }

    public DataPermission getCrtUserBookPermission() {
        User crtUser = PMPHAppUtil.getCrtUser();
        // 查看当前用户的图书数据权限;
        List<DataPermission> crtUserDataPermissionList = lambdaQuery().eq(DataPermission::getUserName, crtUser.getUserName()).list();
        if (CollectionUtils.isNotEmpty(crtUserDataPermissionList)) {
            // 当前用户图书数据权限, 最多只有一条, 如果不为空(说明有限制), 直接返回, 否则取角色权限;
            DataPermission dataPermission = crtUserDataPermissionList.get(0);
            if (CollectionUtils.isNotEmpty(dataPermission.getBookIdArray())
                    || CollectionUtils.isNotEmpty(dataPermission.getBookCategoryArray())) {
                return dataPermission;
            }
        }
        // 当前用户图书数据权限不存在(或无限制), 则查询当前用户所有角色的图书数据权限;
        List<DataPermission> crtRoleListDataPermissionList = lambdaQuery().in(DataPermission::getRoleId, crtUser.getRoleIds()).list()
                .stream().filter(item -> CollectionUtils.isNotEmpty(item.getBookCategoryArray()) || CollectionUtils.isNotEmpty(item.getBookIdArray()))
                .collect(Collectors.toList());
        List<Object> bookCategoryArray = crtRoleListDataPermissionList.stream()
                .filter(item -> CollectionUtils.isNotEmpty(item.getBookCategoryArray()))
                .flatMap(item -> item.getBookCategoryArray().stream())
                .distinct().collect(Collectors.toList());
        List<Object> bookIdArray = crtRoleListDataPermissionList.stream()
                .filter(item -> CollectionUtils.isNotEmpty(item.getBookIdArray()))
                .flatMap(item -> item.getBookIdArray().stream())
                .distinct().collect(Collectors.toList());
        // 如果权限不为空, 返回权限交集;
        if (CollectionUtils.isNotEmpty(bookCategoryArray) || CollectionUtils.isNotEmpty(bookIdArray)) {
            DataPermission dataPermission = new DataPermission();
            dataPermission.setBookCategoryArray(JSON.parseArray(JSON.toJSONString(bookCategoryArray)));
            dataPermission.setBookIdArray(JSON.parseArray(JSON.toJSONString(bookIdArray)));
            return dataPermission;
        }
        // 否则返回空;
        return null;
    }

    public LambdaQueryChainWrapper<Book> filterByBookPermission(LambdaQueryChainWrapper<Book> query) {
        // 获取当前用户bookPermission;
        DataPermission dataPermission = bookPermissionService.getCrtUserBookPermission();
        if (Objects.nonNull(dataPermission)) {
            return query.and(item -> {
                item.in(CollectionUtils.isNotEmpty(dataPermission.getBookIdArray()), Book::getId, dataPermission.getBookIdArray());
                // 图书分类为全路径分类, 权限为节点id, like;
                for (String bookCategory : dataPermission.getBookCategoryArray().toJavaList(String.class)) {
                    item.or().like(Book::getCategory, bookCategory);
                }
            });
        }
        return query;
    }

    public DataPermission selectDataPermission(String userName, String roleId) {
        DataPermission result = null;
        if (StringUtils.isNotEmpty(userName)) {
            result = lambdaQuery().eq(DataPermission::getUserName, userName).one();
        }
        else if (StringUtils.isNotEmpty(roleId)){
            result = lambdaQuery().eq(DataPermission::getRoleId, roleId).one();
        }
        if (Objects.isNull(result)) {
            result = new DataPermission();
            result.setUserName(userName);
            result.setRoleId(roleId);
        }
        return result;
    }

    public void saveDataPermission(DataPermission dataPermission) {
        bookPermissionService.saveOrUpdate(dataPermission);
    }
}
